
#ifndef _GRABBERCB_
#define _GRABBERCB_

// Added to have compatibility with November 2007 SDK
#define __IDxtCompositor_INTERFACE_DEFINED__
#define __IDxtAlphaSetter_INTERFACE_DEFINED__
#define __IDxtJpeg_INTERFACE_DEFINED__
#define __IDxtKey_INTERFACE_DEFINED__


#include <qedit.h>   // Sample grabber

#include "Histogram.h"
#include "Utils.h"
#include "output_sail.h"

class C_GrabProc {
	
//	static GrabberCB m_grabberCallback;  // Make this global so that it stays in scope while the graph exists
	// create filter------------
	AM_MEDIA_TYPE m_mt;
	AM_MEDIA_TYPE m_audiomt;
	CComPtr<IBaseFilter> m_pGrabF;
	CComPtr<IBaseFilter> m_pAudioGrabF;
	CComPtr<IBaseFilter> m_pYUVtransF;
	int m_sub_type;
	// send image---------------
    BYTE*   m_pImg;
    BYTE*   m_pAudioSamples;
    DWORD   m_dwWidth;
    DWORD   m_dwHeight;
    LONG    m_lStride;
    int     m_iBitDepth;
	int		m_out_color_mode;
	unsigned char* m_pbRGB_buff;
	DWORD m_bufLen;
	bool m_sageOn;
	CString m_ip;

	class C_Output_sail Out_sail;

public :
	// create filter------------
	C_GrabProc(void);
	void FreeFilter(void);
	HRESULT SetFilter(IGraphBuilder* pGraph, IBaseFilter* pUpstream, wchar_t* pUpstreamPinName, int out_color_mode, bool sage=false);
	HRESULT SetAudioFilter(IGraphBuilder* pGraph, IBaseFilter* pUpstream, wchar_t* pUpstreamPinName);
	IBaseFilter* GrabF(void);
	// send image---------------
	HRESULT SetVideoFormat(const VIDEOINFOHEADER& vih, int out_color_mode);
    HRESULT SetImageBuffer(BYTE *pBuffer);
    HRESULT SetAudioBuffer(BYTE *pBuffer);
	HRESULT ConvertImage();
	int SendToBmp(void);
	int SendToSage(void);
	int SendAudioToSage(int buflen);
	void setIP(CString ip);

	void SetAudioOn(bool on);
	void SetAudioCaptureMode(bool on);
	void Shutdown();

	bool GetSageOn();
};

// GrabberCB: Class to implement the callback function for the sample grabber
// Note: No ref-counting, so keep the object in scope while you're using it!
class GrabberCB : public ISampleGrabberCB 
{
private:
    BITMAPINFOHEADER m_bmi;  // Holds the bitmap format 
    bool m_fFirstSample;     // true if the next sample is the first one.

public:

    GrabberCB();
    ~GrabberCB();

	C_GrabProc m_GrabProc;
	int m_out_color_mode;

    // IUnknown methods
    STDMETHODIMP_(ULONG) AddRef() { return 1; }
    STDMETHODIMP_(ULONG) Release() { return 2; }
    STDMETHOD(QueryInterface)(REFIID iid, void** ppv);

    // ISampleGrabberCB methods
    STDMETHOD(SampleCB)(double SampleTime, IMediaSample *pSample);
    STDMETHODIMP BufferCB(double, BYTE *, long) { return E_NOTIMPL; }

};

// AudioGrabberCB: Class to implement the callback function for the sample grabber
// Note: No ref-counting, so keep the object in scope while you're using it!
class AudioGrabberCB : public ISampleGrabberCB 
{
private:
    BITMAPINFOHEADER m_bmi;  // Holds the bitmap format 
    bool m_fFirstSample;     // true if the next sample is the first one.
	int m_index;
public:

    AudioGrabberCB();
    ~AudioGrabberCB();

	C_GrabProc* m_GrabProc;

    // IUnknown methods
    STDMETHODIMP_(ULONG) AddRef() { return 1; }
    STDMETHODIMP_(ULONG) Release() { return 2; }
    STDMETHOD(QueryInterface)(REFIID iid, void** ppv);

    // ISampleGrabberCB methods
    STDMETHOD(SampleCB)(double SampleTime, IMediaSample *pSample);
    STDMETHODIMP BufferCB(double, BYTE *, long) { return E_NOTIMPL; }

};

// GUID media_type_ary[] = {MEDIASUBTYPE_UYVY, MEDIASUBTYPE_YUY2, MEDIASUBTYPE_YUYV};

#ifdef _MAIN_
GrabberCB grabberCallback;  // Make this global so that it stays in scope while the graph exists
AudioGrabberCB AudioGrabCallback; 
#else
extern GrabberCB grabberCallback;  // Make this global so that it stays in scope while the graph exists
extern AudioGrabberCB AudioGrabCallback; 
#endif


#endif